﻿using System;
using System.Data.Common;
using System.Web.Hosting;

namespace Jayden.Dll.Core.Persistence.Data
{
	public class DbConnectionProxy : IDisposable
	{
		private Type m_ConnectionType;
		private string m_ConnectionString;
		protected DbConnection m_Connection;
		protected DbTransaction m_Transaction;

		public DbConnectionProxy(Type type, string connectionString)
		{
			m_ConnectionString = connectionString;
			m_ConnectionType = type;
		}

		public string ConnectionString { get { return m_ConnectionString; } }

		public bool InTransation { get { return m_Transaction != null; } }
		public virtual void BeginTransaction()
		{
			if (m_Transaction == null)
				m_Transaction = Connection.BeginTransaction();
			else
				throw new InvalidOperationException();
		}
		public virtual void CommitTransaction()
		{
			if (m_Transaction == null)
				throw new InvalidOperationException();
			m_Transaction.Commit();
			m_Transaction.Dispose();
			m_Transaction = null;
		}
		public virtual void RollbackTransaction()
		{
			if (m_Transaction == null)
				throw new InvalidOperationException();
			m_Transaction.Rollback();
			m_Transaction.Dispose();
			m_Transaction = null;
		}
		public virtual DbConnection Connection
		{
			get
			{
				if (m_Connection == null)
				{
					m_Connection = Activator.CreateInstance(m_ConnectionType) as DbConnection;
					string hostedPath = HostingEnvironment.MapPath("/");
					if (hostedPath == null)
					{
						hostedPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
						if (hostedPath.StartsWith("file:\\"))
							hostedPath = hostedPath.Substring(6);
					}
					m_Connection.ConnectionString = string.Format(m_ConnectionString, hostedPath);
					m_Connection.Open();
				}
				return m_Connection;
			}
		}

		public virtual void Close()
		{
			if (m_Transaction != null)
			{
				m_Transaction.Rollback();
				m_Transaction.Dispose();
			}
			if (m_Connection != null)
			{
				m_Connection.Close();
				m_Connection.Dispose();
			}
			m_Connection = null;
		}

		public virtual DbCommandProxy CreateCommand(string commandText = null)
		{
			DbCommand dbCommand = Connection.CreateCommand();
			dbCommand.CommandText = commandText;
			return new DbCommandProxy(this, dbCommand);
		}

		public void Dispose() { Close(); }
	}
}
